#include "dpidef.h"
#include "user_space.h"
#include "kernel_space.h"
#include "common.h"
#include "stdlib.h"
#include "stdio.h"

int LoadPackets(FILE *file, int *Dest, int Count)
{
  unsigned int PAddr, DAddr, Tail;
  unsigned int TagH, TagL;
  unsigned int *Buf;
  int i,j;
  int Bytes;
  char c;
  unsigned int Data;

  printf("LoadPackets %0x %d", Dest, Count);
  i = 0;
  DAddr = (unsigned int)Dest & 0xFFFFFFF0;
  Tail = 0;
  Buf = (int*) malloc(65536);
  while (!feof(file) && (i++ <Count))
  {
    if (fscanf(file, "%x %x %c", &TagH, &TagL, &c) != 3) break;
    for(j=0; j<1024; j++)
    {
      if(fscanf(file, "%x", &Data) != 1) 
        break;
      else
        Buf[j] = Data;
    }
    while(!feof(file) && (fgetc(file) != '\n'));
    if(j>0)
    {
      PAddr = DAddr + 16;
      Write(PAddr, Buf, 4*j, &Bytes);
    
      Buf[0] = 0;
      Buf[1] = PAddr;
      Buf[2] = (TagL << 16) | 4*j;
      Buf[3] = TagH;
      Write(DAddr, Buf, 16, &Bytes);
      if (Tail)
        MemWriteDW(Tail, DAddr);
      Tail = DAddr;
      DAddr = ((unsigned int)(PAddr + 4*j + 15)) & 0xFFFFFFF0;
    }
  }
  free(Buf);
  return i;
}

int StorePackets(FILE *file, int *Src, int Count)
{
  int *DAddr;
  int *PAddr;
  unsigned int *Buf;
  int i,j;
  int Bytes;
  int Length;
  unsigned long long Tag;
  DAddr = Src;
  i = 0;
  Buf = (int*) malloc(65536);
  while (DAddr && (i++ < Count))
  {
    Read(DAddr, Buf, 16, &Bytes);
    DAddr = Buf[0];
    PAddr = Buf[1];
    Length = Buf[2] & 0xFFFF;
    fprintf(file, "%08X %04X :", Buf[3], (Buf[2]>>16));
    Read(PAddr, Buf, Length, &Bytes);
    for(j=0; j < Length/4; j++)
      fprintf(file, " 0x%08X", Buf[j]);
    fprintf(file, ";\n");
  }
  free(Buf);
  return i;
}

int DisplayPackets(int *Src, int Count)
{
  int *DAddr;
  int *PAddr;
  unsigned int *Buf;
  int i,j;
  int Bytes;
  int Length;
  unsigned long long Tag;
  DAddr = Src;
  i = 0;
  Buf = (int*) malloc(65536);
  while (DAddr && (i++ < Count))
  {
    Read(DAddr, Buf, 16, &Bytes);
    DAddr = Buf[0];
    PAddr = Buf[1];
    Length = Buf[2] & 0xFFFF;
    Tag = Buf[3];
    Tag = (Tag << 16) | (Buf[2] >> 16);
    Read(PAddr, Buf, Length, &Bytes);
    printf("0x%016llx :", Tag);
    for(j=0; j <= Length/4; j++)
      printf(" 0x%08X", Buf[j]);
    printf("\n");
  }
  free(Buf);
  return i;
}

void PostProcess(int **ppDescriptor)
{
  int *ListHead;
  int *NewListHead;
  int NextNode;
  ListHead = *ppDescriptor;
  NewListHead = 0;
  while(ListHead)
  {
    MemReadDW(ListHead, &NextNode);
    MemWriteDW(ListHead, NewListHead);
    NewListHead = ListHead;
    ListHead = NextNode;
  }
  *ppDescriptor = NewListHead;
}

int user_main()
{
  int BytesRead;
  FILE *ofile;
  FILE *ifile;
  TDescriptor *pDescriptor = 0x2000;
  unsigned int State;  
  
  printf("Begin main()\n");

  printf("Loading packets from File\n");
  ifile = fopen("input.txt", "r");
  LoadPackets(ifile, pDescriptor, 100);
  fclose(ifile);

  printf("Setting up Recorder\n");
  RegWriteDWord(0x24, 0x0);     //Start Page Addr
  RegWriteDWord(0x2C, 0x1000);  //End Page Addr
  RegWriteByte(0x20, 0x1);      //Enable Recorder

  printf("Setting up Player\n");
  RegWriteDWord(0x4, pDescriptor);  //First Descriptor Address
  RegWriteByte(0x0, 0x1);           //Enable Player
  
  printf("Waiting for Player to finish\n");
  do
  {
    RegReadDWord(0x0, &State);
    State = (State & 0x000F0000) >> 16;
  } while(State != 0x6);
  RegWriteDWord(0x0, 0x0);  //Disable Player
  
  
  RegWriteDWord(0x20, 0x0); //Disable Recorder
  do
  {
    RegReadDWord(0x20, &State);
    State = (State & 0x000F0000) >> 16;
  }while(State !=0);
  
  RegReadDWord(0x28, &pDescriptor);
  
  ofile = fopen("output.txt", "w");
  StorePackets(ofile, pDescriptor, 100);
  fclose(ofile);

  printf("End main()\n");
  return 0;
}
